/**
 * @description a 可能没有 sum() 方法， 但是想要用这个方法， 那怎么办呢， 就去借用别人的
 * @param context 上下文， 如果没有， 那就是当前的document
 * @param arg  需要传进来的参数
 */

// let a = 19;
// let sum = (b) => {
//     console.log( a + b)
// }
//
// // 就是a要用sum方法， 那么怎么办呢， 就去借用sum方法
// sum.call(a, 1000)
//
// Function.prototype.myCall= (context, arg)=>{
//     // 如果没有上下文， 那么就赋值给window
//     const ctx = context || window
//     ctx.func = this
//     const res  = arg.length > 1?ctx.func(...arg):ctx.func()
//     delete ctx.func
//     return res
// }
//
// sum.myCall(a, 1000)



Function.prototype.myCall = function (context, ...args) {
    // 如果没有指定上下文， 那就是默认的全局上下文
    context = context || window

    // 给上下文添加一个属性， 该属性是this， 保存一下this作用域
    const symbol = Symbol('fn')
    context[symbol] = this;

    // 调用this下面的方法
    const res = context[symbol](...args)
    delete context[symbol]
    return res;
}

const obj = {
    name: 'ck'
}

// console.log(Math.abs.myCall(obj, 10));



function myCall(context, args){
    context= context || window
    const symbol =  Symbol('ck')
    context[symbol]  = this;
    context[symbol](...args)
    delete context[symbol]
}


Function.prototype.call2 = function (context){
    // 第一个参数是环境， 如果没有环境就是全局
    context = context || window
    // this 就是第一个参数
    context.fn = this
    console.log(this)
    // 去掉第一个参数后的所有参数， arguments是类数组
    // const args = Array.from(arguments).slice(1)
    // const args = Array.prototype.slice.call(arguments).slice(1)
    const args = [...arguments].slice(1)
    // 执行一下第一个参数的方法
    context.fn(...args)
    // 删除当前的这个方法
    delete context.fn
}

function add(a,b){
    console.log(a + b)
}

function P(){

}

// 这里的add就是this的指向
// add.call2(P,1,2)


Function.prototype._call=function (context=window){
    const args = [...arguments].slice(1)
    context.fn = this;

    console.log('this',this)
    context.fn(...args)
    delete context.fn
    //删除掉了，这里就没有了
    console.log('fnnnn',context.fn)

}

const sum =()=>{}
const sumObj={
    sub:(num)=>{
        console.log('sub',num)
    }
}

sumObj.sub._call(sum,10)



Function.prototype.__call = function (context) {
  context = context || window;

  context.fn = this;

  const args = [...arguments].slice(1);
  const res = context.fn(...args);
  delete context.fn;
  return res;
};